import java.io.Serializable;
import java.rmi.RemoteException;
import javax.swing.table.DefaultTableModel;

import common_classes.WSEvent;

import common_classes.AuctionPrimitiveData;
import common_classes.AuctionStates;
import common_classes.BidPriceData;
import common_classes.ProviderData;
import FlexTrade.WSAdaptor;

public class Provider implements Serializable, Runnable {
	  /**
	 * 
	 */
	private static final long serialVersionUID = -4960985871870934443L;
	private static final long WAITFOR = 100000L;
	  private static final long EVENT_RECEIVE_INTERVAL = 3000;
	  private WSAdaptor service;
	  private ProviderData providerData;
	  private boolean stopThread = false;
	  //reference to the text field in main frame UI
	  public javax.swing.JTextArea txtText = null;
	  //detail information of this auction.
	  public AuctionPrimitiveData auctionPrimitiveData;
	  //table model
	  public DefaultTableModel model;
	/**
	 * @param args
	 */

	public Provider() {
	}
	
	public void setEventLog(javax.swing.JTextArea _txt) {
		this.txtText = _txt;
	}

	public void setService(WSAdaptor _adapter) {
		this.service = _adapter;
	}
	
	public void setProviderData(ProviderData _providerData) {
		this.providerData = _providerData;
	}
	
	public void stopEventThread() {
		stopThread = true;
	}
	
	public void pullEvents(String _uniqueAuctionID) {
		// TODO Auto-generated method stub
		AuctionStates auctionStates;
		String messageLog = "";
		WSEvent[] eventList = null;
		WSEvent t_event = null;
		int eventID = -1;
		
		try {
			eventList = service.pullWSEvents(_uniqueAuctionID, this.providerData.getUniqueProviderID());
			if (eventList == null) return;
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//the final status when the event occurs
		BidPriceData bidPriceData;
		//get the current status of this auction
 
		for (int i = 0; i < eventList.length; i++) {
			t_event = eventList[i];
			eventID = (int) t_event.getEventID();
			auctionStates = t_event.getAuctionStates();
			t_event.getAuctionPrimitiveData();
			switch (eventID) {
			case IAuction.E_NEW_AUCTION:
				messageLog = FlexTradeUtils.currentTime() + ": New English auction ID " + _uniqueAuctionID;
				messageLog = messageLog + "by provider " + providerData.getUniqueProviderID() + " has just created.";
				break;
			case IAuction.V_NEW_AUCTION:
				messageLog = FlexTradeUtils.currentTime() + ": New Vickrey auction ID " + _uniqueAuctionID;
				messageLog = messageLog + "by provider " + providerData.getUniqueProviderID() + " has just created.";
				break;
			case IAuction.D_NEW_AUCTION:
				messageLog = FlexTradeUtils.currentTime() + ": New Dutch auction ID " + _uniqueAuctionID;
				messageLog = messageLog + "by provider " + providerData.getUniqueProviderID() + " has just created.";
				break;
			case IAuction.E_AUCTION_FINISH:
				messageLog = (FlexTradeUtils.currentTime() + ": Auction " +  _uniqueAuctionID + " is finished");
				break;
			
			case IAuction.E_BID_PRICE_RECEIVED:
				bidPriceData = t_event.getLastBidPriceData();
				messageLog = FlexTradeUtils.currentTime() + ": Received bid price of " + bidPriceData.getBidPrice() + " from customer ";
				messageLog = messageLog + bidPriceData.getCustomer().getUniqueCustomerID() + " for auction";
				messageLog = messageLog + _uniqueAuctionID;
				break;
			
			case IAuction.E_CUSTOMER_JOIN:
				messageLog = FlexTradeUtils.currentTime() + ": New customer has just joined the auction " + _uniqueAuctionID;
				break;
			
			case IAuction.V_AUCTION_FINISH:
				messageLog = (FlexTradeUtils.currentTime() + ": Auction " +  _uniqueAuctionID + " is finished");
				break;
			
			case IAuction.V_BID_PRICE_RECEIVED:
				bidPriceData = t_event.getLastBidPriceData();
				messageLog = FlexTradeUtils.currentTime() + ": Received bid price of " + bidPriceData.getBidPrice() + " from customer  ";
				messageLog = messageLog + bidPriceData.getCustomer().getUniqueCustomerID() + " for auction ";
				messageLog = messageLog + _uniqueAuctionID;
				break;
			
			case IAuction.V_CUSTOMER_JOIN:
				messageLog = FlexTradeUtils.currentTime() + ": New customer has just joined the auction " + _uniqueAuctionID;
				break;
			
			case IAuction.D_ACCEPTABLE_PRICE_RECEIVED:
				messageLog = FlexTradeUtils.currentTime() + ": Received new offer of ";
				messageLog = messageLog + Float.toString(auctionStates.getAcceptableBidPrice()) + " for auction ID "; 
				messageLog = messageLog + _uniqueAuctionID;
				break;
		
			case IAuction.D_CUSTOMER_JOIN:
				messageLog = FlexTradeUtils.currentTime() + ": New customer has just joined the auction " + _uniqueAuctionID;
				break;
	
			case IAuction.D_CUSTOMER_ACCEPT:
				bidPriceData = t_event.getLastBidPriceData();
				messageLog = FlexTradeUtils.currentTime() + ": Customer " + bidPriceData.getCustomer().getUniqueCustomerID();
				messageLog = messageLog + " accepted price of " + bidPriceData.getBidPrice() + " for auction ID ";
				messageLog = messageLog + _uniqueAuctionID;
				break;
			
			case IAuction.D_AUCTION_TIMEOUT:
				messageLog = FlexTradeUtils.currentTime() + " Auction ID " + _uniqueAuctionID;
				messageLog = messageLog + " is time out. No customer accepts your offer.";
				break;
				
			case IAuction.CANNOT_TRANSFER_PAYMENT:
				messageLog = FlexTradeUtils.currentTime() + ": Error. Payment transaction for auction  " + _uniqueAuctionID;
				messageLog = messageLog + " is not successful. This auction is aborted.";
				break;
				
			case IAuction.PAYMENT_TRANSFERED_SUCCESSFULLY:
				messageLog = FlexTradeUtils.currentTime() + ": Payment transaction for auction  " + _uniqueAuctionID;
				messageLog = messageLog + " is successful. Prepare to ship goods to customer";
				break;
			
			default:
				System.out.println(FlexTradeUtils.currentTime() + ": Invalid event ID occurs");	
			}
	}
		//diplay logging message to main frame UI
		this.setText(messageLog);
	}
	
	public void setTableModel(DefaultTableModel _model) {
		this.model = _model;
	}
	
	public DefaultTableModel getTableModel(){
		return this.model;
	}
	
	//Get reference to text area in main form
	public void setTextField(javax.swing.JTextArea txt){
		this.txtText = txt;
	}
	
	//Print message to textfield in main form
	public void setText(String message){
		txtText.append(message + "\n");
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		AuctionPrimitiveData[] listOfAuctions = null;
		while (!stopThread) {
			try {
				Thread.sleep(EVENT_RECEIVE_INTERVAL);
				listOfAuctions = service.getCurrentActiveAuctions();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (listOfAuctions != null) {
				for (int i = 0; i < listOfAuctions.length; i++) {
					pullEvents(listOfAuctions[i].getUniqueAuctionID());
				}
			}
		}
	}
}